var content = require('../../../public/content');
var data = require('{pub}/data');
var tpl = require('../../../views/voucher/record');
var template = require('template');
var numeral = require('{plus}/numeral');
var request = require('request');
var util = require('util');
var layer = require('layer');
var subject = require('./subject/subject');
var calendar = require('{plus}/calendar');

//将单元格恢复默认状态
Nui.doc.click(function(){
    $('.voucher-tbody .cell-edit.s-crt').removeClass('s-crt');
})

var voucherWwapper;
//ctrl+s保存
Nui.doc.keydown(function(e){
    if(voucherWwapper && voucherWwapper.is(':visible') && e.ctrlKey === true && e.keyCode === 83){
        voucherWwapper.save();
        return false
    }
})

return extend(content, {
    target:'#record-voucher',
    path:'voucher',
    template:tpl,
    wrapper:true,
    data:{
        title:'记账凭证'
    },
    events:{
        'mouseenter .table-row':'showButton',
        'mouseleave .table-row':'mouseleave',
        'mouseenter .col-subject .cell-edit-text':'showDetail',
        'mouseleave .col-subject .cell-edit-text':'mouseleave',
        'click .cell-edit':'showEdit',
        'keydown .cell-input':'dirFocus',
        'keydown .col-summary .cell-input':'enterTabBoard nextFocus',
        'keydown .col-number .cell-input, .col-currency .cell-input':'enterTabBoard nextFocus',
        'keydown .col-debit .cell-input':'getType spaceBoard enterTabBoard nextTrFocus nextFocus',
        'keydown .col-credit .cell-input':'getType spaceBoard enterTabBoard isValue nextFocus lastAddrow',
        'keyup .input-money':'equalBoard getType editing',

        'keyup .row-account .input-money':'countPrice_account countBalance',
        'keyup .row-account .input-adjust':'getMoney countMoney_account countBalance',
        'keyup .row-currency .input-money':'countRate_currency countBalance',
        'keyup .row-currency .input-adjust':'getMoney countMoney_currency countBalance',

        'blur .col-summary .cell-input':'summaryBlur setText',
        'blur .input-money':'moneyBlur setText',
        'click .cell-input':'inputClick',
        'click .j-addrow':'addrow',
        'click .j-delrow':'delrow total',
        'click .j-save, .j-saveadd':'enabled save',
        'click .m-main-header .j-next':'enabled nextVoucher',
        'click .m-main-header .j-prev':'enabled prevVoucher',
        'click .ui-input-date':'showDate'
    },
    detailTimer:null,
    bindSave:function(){
        var that = this;
        voucherWwapper = that.element;
        voucherWwapper.save = function(){
            that.save();
        }
    },
    initData:function(){
        data.set('summary');
        data.set('subject');
        this.data.vouchers = new Array(4);
    },
    onChange:function(){
        content.onChange.call(this);
        this.bindSave();
    },
    onInit:function(self){
        if(self){
            this.layer = self;
            this.element = self.element;
            this.bindSave();
        }
        this.initTemplate();
        subject.call(this);
    },
    initTemplate:function(){
        var that = this;
        request.get('voucher.json', {}, {
            200:function(res){
                that.render(res.data)
            }
        }, '正在初始化凭证...', this.layer)
    },
    render:function(res){
        var that = this, data = that.data;
        delete data.vouchers;
        delete data.isAccount;
        delete data.isCurrency;
        var count = res.vouchers.length - 4;
        if(count < 0){
            count = Math.abs(count);
            while(count){
                res.vouchers.push({});
                count--
            }
        }
        that.data = $.extend(data, res);

        Nui.each(that.data.vouchers, function(v, k){
            if(v.isAccount){
                data.isAccount = true;
            }
            if(v.isCurrency){
                data.isCurrency = true;
            }
        })
        content.render.call(this);
        that.serialize = that.getSerialize();
        that.total();
    },
    renderButton:function(){
        var data = this.data;
        delete data.allowSave;
        if(
            this.getSerialize() !== this.serialize && 
            (
                data.total_credit === data.total_debit
            )
            
        ){
            data.allowSave = true
        }
        this.element.find('.voucher-button').html(template.render.call(tpl, tpl.button, this.data))
    },
    //初始化组件
    initCom:function(elem){
        var that = this;
        var opts = {
            callback:function(elem){
                if(elem.hasClass('cell-input')){
                    setTimeout(function(){
                        that.total();
                    })
                }
            }
        }
        if(!elem){
            this.element.find('[data-integer]').numeral(opts)
        }
        else{
            elem.find('[data-integer]').numeral(opts)
        }
    },
    nextVoucher:function(e, elem){
        
    },
    prevVoucher:function(e, elem){
        
    },
    //保存凭证
    save:require('./save'),
    //返回表单序列化字符串，用于比对新旧数据
    getSerialize:function(){
        return this.element.find('form').serialize();
    },
    //显示删除新增按钮
    showButton:function(e, elem){
        elem.addClass('s-hover')
    },
    //隐藏删除新增按钮
    mouseleave:function(e, elem){
        clearTimeout(this.detailTimer);
        elem.removeClass('s-hover')
    },
    //显示完整科目与摘要
    showDetail:function(e, elem){
        clearTimeout(this.detailTimer);
        this.detailTimer = setTimeout(function(){
            elem.addClass('s-hover')
        }, 300)
    },
    //编辑单元格
    showEdit:function(e, elem){
        this.element.find('.cell-edit.s-crt').removeClass('s-crt');
        elem.addClass('s-crt').find('.cell-input').eq(0).focus().select();
        e && e.stopPropagation();
    },
    //回车以及tab键
    enterTabBoard:function(e){
        var keycode = e.keyCode;
        if(keycode === 9 || keycode === 13){
            e.preventDefault();
            return keycode
        }
        return false
    },
    //等号键
    equalBoard:function(e, elem){
        if(e.keyCode == 187){
            var value = '';
            elem.val(' ');
            this.editing(e, elem, this.getType(e, elem));
            elem.val(value);
            this.total();
            var debit = this.data.total_debit || 0;
            var credit = this.data.total_credit || 0;
            if(elem.attr('name') === 'debitAmt'){
                value = credit - debit;
            }
            else{
                value = debit - credit;
            }
            elem.val(util.toFixed(value, 2));
            e.preventDefault();
            return false;
        }
    },
    //空格切换值
    spaceBoard:function(e, elem, type){
        var editElem = elem.closest('td')[type]().children();
        var inputElem = editElem.find(':text');
        if(e.keyCode === 32){
            var value = elem.val();
            if(value){
                inputElem.val(value);
                elem.val('');
            }
            this.showEdit(e, editElem);
            e.preventDefault();
            return false
        }
    },
    editing:function(e, elem, type){
        var inputElem = elem.closest('td')[type]().children().find(':text');
        if(elem.val() !== ''){
            //表示当前正在编辑的金额栏
            elem.addClass('editing');
            //金额栏只能一个有值
            this.setText(e, inputElem.removeClass('editing'), '')
        }
    },
    getType:function(e, elem){
        var type;
        if(elem.attr('name') === 'debitAmt'){
            type = 'next'
        }
        else{
            type = 'prev'
        }
        return type;
    },
    //数量外币核算计算金额
    countMoney:function(e, elem){

    },
    //如果借贷金额都没值，切换到借方单元格
    isValue:function(e, elem, keycode){
        var debitEdit = elem.closest('td').prev().children();
        if(!elem.val() && !debitEdit.find(':text').val()){
            this.showEdit(e, debitEdit);
            return false
        }
        return keycode
    },
    //借方金额有值，回车或者tab直接定位到摘要
    nextTrFocus:function(e, elem, keycode){
        if(elem.val()){
            this.nextFocus(e, elem.closest('td').next().find('.input-money'));
            this.lastAddrow(e, elem);
            return false
        }
        return keycode
    },
    //回车、Tab切换到下一个单元格
    nextFocus:function(e, elem){
        if(!e){
            e = {
                preventDefault:$.noop,
                stopPropagation:$.noop,
                keyCode:13
            }
        }
        this.horzFocus(e, elem, 'next');
    },
    //水平向键切换上一个单元格
    horzFocus:function(e, elem, type, dir){
        var dom = elem.get(0), keycode = e.keyCode;
        //金额栏焦点不在开始位置时，光标可在输入框内移动
        if(dir && elem.hasClass('input-money')){
            var index = util.getFocusIndex(dom);
            var edge;
            if(type === 'prev'){
                edge = index !== 0;
            }
            else{
                edge = index !== dom.value.length;
            }
            if(!util.isTextSelect() && edge){
                return true
            }
        }

        var td = elem.closest('td');
        if(dom.nodeName === 'TD'){
            td = elem;
        }
        else if(keycode === 13 || keycode === 9){
            var index = 0;
            var inputs = td.find('.cell-input');
            inputs.each(function(i){
                if(dom === this){
                    index = i;
                }
            });
            var nextInput = inputs.eq(index+1);
            if(nextInput.length && !nextInput.prop('readonly')){
                nextInput.focus();
                return false;
            }
        }

        var tr = td.closest('tr');
        var _td = td[type]('td');
        var _tr = tr[type]('tr');
        var _edit = _td.children('.cell-edit');
        if(_td.length){
            if(_td.is(':visible') && _edit.length){
                this.showEdit(e, _edit);
            }
            else{
                this.horzFocus(e, _td, type)
            }
        }
        else if(_tr.length){
            this.showEdit(e, _tr.find('td:eq('+ (type === 'prev' ? -1 : 1) +') .cell-edit'));
        }
        e.preventDefault();
    },
    //垂直方向切换单元格
    verticalFocus:function(e, elem, type){
        var td = elem.closest('td');
        var index = td.index();
        var celledit = td.closest('tr')[type]().find('td').eq(index).children('.cell-edit');
        if(celledit.length){
            this.showEdit(e, celledit);
        }
        e.preventDefault();
    },
    //方向键切换单元格
    dirFocus:function(e, elem){
        var that = this, keycode = e.keyCode;
        if(keycode >= 37 && keycode <= 40){
            switch(keycode){
                case 37:
                    that.horzFocus(e, elem, 'prev', true)
                    break;
                case 38:
                    that.verticalFocus(e, elem, 'prev')
                    break;
                case 39:
                    that.horzFocus(e, elem, 'next', true)
                    break;
                case 40:
                    that.verticalFocus(e, elem, 'next')
                    break;
            }
        }
    },
    lastAddrow:function(e, elem){
        if(!elem.closest('tr').next().length){
            this.addrow(e, elem)
        }
    },
    //新增一行
    addrow:function(e, elem, isFocus){
        var tr = $(template.render.call(tpl, tpl.row, {})).insertAfter(elem.closest('tr'));
        if(isFocus !== false){
            this.showEdit(e, tr.find('td:eq(1) .cell-edit'));
        }
    },
    //删除行
    delrow:function(e, elem){
        elem.closest('tr').remove();
        if(this.element.find('.table-row').length < 4){
            this.addrow(e, this.element.find('.table-row:last'), false)
        }
    },
    summaryBlur:function(e, elem){
        return elem.val()
    },
    moneyBlur:function(e, elem){
        return elem.val()
    },
    setText:function(e, elem, value){
        if(!value){
            value = '';
        }
        var textElem = elem.closest('.cell-edit').find('.cell-text');
        if(elem.hasClass('input-money')){
            var max = 999999999.99;
            var min = max * -1;
            if(!parseFloat(value)){
                value = ''
            }
            if(value > max){
                value = max
            }
            else if(value < min){
                value = min
            }
            elem.val(value = util.toFixed(value, 2));
            textElem.removeClass('f-cred').addClass(value < 0 ? 'f-cred' : '');
            value = value.replace(/[.-]/g, '').replace(/^0+/, '');
            textElem.text(value);
        }
        else{
            textElem.text(value);
        }
    },
    //点击输入框，单元格高亮
    inputClick:function(e, elem){
        this.element.find('.cell-edit.s-crt').removeClass('s-crt');
        elem.closest('.cell-edit').addClass('s-crt');
        e.stopPropagation();
    },
    //借贷金额合计
    total:function(){
        this.data = $.extend(this.data, {
            total_cn:'',
            total_debit:'',
            total_credit:''
        })
        var data = this.data;
        var max = 999999999.99;
        var min = max*-1;
        var debit = 0;
        var credit = 0;
        this.element.find('.table-row').each(function(){
            var tr = $(this);
            debit += parseFloat(tr.find('.col-debit :text').val()||0);
            credit += parseFloat(tr.find('.col-credit :text').val()||0);
        });

        if(debit > max){
            debit = max;
        }
        else if(debit < min){
            debit = min;
        }
        if(credit > max){
            credit = max;
        }
        else if(credit < min){
            credit = min;
        }

        if(debit){
            data.total_debit = debit = util.toFixed(debit, 2);
        }
        if(credit){
            data.total_credit = credit = util.toFixed(credit, 2);
        }

        if(debit && credit && debit === credit){
            data.total_cn = util.numberToCN(debit)
        }

        this.element.find('.voucher-tfoot').html(template.render.call(tpl, tpl.total, data))

        this.renderButton();
    },
    //获取借贷金额有值的元素
    getElement:function(e, elem){
        var tr = elem.closest('tr');
        var _elem = tr.find('.input-money[value!=""]');
        //都不存在值
        if(!_elem.length){
            _elem = tr.find('.input-money.editing');
            //没有编辑状态
            if(!_elem.length){
                _elem = tr.find('.col-debit .input-money')
            }
        }
        return _elem;
    },
    //获取金额
    getMoney:function(e, elem){
        return this.getElement(e, elem).val() || 0
    },
    //计算余额
    countBalance:require('./balance'),
    //反算结果
    //数量核算：单价 = 金额 / 数量
    //外币（数量）核算：汇率 = 金额 / 原币
    //数量外币核算：原币 = 数量 * 单价
    //数量外币核算：单价 = 原币 / 数量
    countValue:function(v1, v2, symbol, decimal){
        var value = 0;
        
        if(v1 && v2){
            if(symbol === '*'){
                value = v1 * v2
            }
            else{
                value = v1 / v2
            }
        }

        if(!value){
            value = '';
        }
        else{
            value = util.toFixed(value, decimal||4, 0)
        }
        return value;
    },
    //金额和数量原币正负方向相同
    equalDir:function(v1, v2){
        return (Math.abs(v1||0) * (v2 < 0 ? -1 : 1) || '');
    },
    //数量核算计算金额
    countMoney_account:function(e, elem, value){
        var td = elem.closest('td');
        var amountElem = td.find('[name="amount"]');
        var priceElem = td.find('[name="price"]');
        var amount = parseFloat(amountElem.val() || 0);
        var price = parseFloat(priceElem.val() || 0);

        //根据数量和金额计算单价
        if(elem.attr('name') === 'amount'){
            //数量和金额正负相同，始终保持单价为正数
            //单价 = 金额 / 数量
            value = this.equalDir(value, amount);
            priceElem.val(this.countValue(value, amount))
        }
        //金额 = 单价 * 数量
        else{
            value = util.toFixed(price * amount, 2);
        }
        this.setText(e, this.getElement(e, elem), value);
    },
    //数量核算金额反算单价
    countPrice_account:function(e, elem){
        var tr = elem.closest('tr');
        var amountElem = tr.find('.col-number [name="amount"]');
        var priceElem = tr.find('.col-number [name="price"]');
        var amount = parseFloat(amountElem.val() || 0);
        var price = 0;
        var value = elem.val();
        amount = this.equalDir(amount, value);
        amountElem.val(amount);
        priceElem.val(this.countValue(value, amount))
    },
    //外币（数量）核算计算金额
    countMoney_currency:function(e, elem, value){
        var tr = elem.closest('tr');
        var amountElem = tr.find('.col-number [name="amount"]');
        var priceElem = tr.find('.col-number [name="price"]');
        var rateElem = tr.find('.col-currency [name="rate"]');
        var moneyElem = tr.find('.col-currency [name="money"]');

        var amount = parseFloat(amountElem.val() || 0);
        var price = parseFloat(priceElem.val() || 0);
        var rate = parseFloat(rateElem.val() || 0);
        var money = parseFloat(moneyElem.val() || 0);
        var name = elem.attr('name');

        switch(name){
            case 'amount' :
            case 'price' :
                // 原币 = 数量 * 单价
                money = this.countValue(amount, price, '*', 2);
                moneyElem.val(money);
                break;
            case 'money' :
                //单价 = 原币 / 数量
                price = this.countValue(money, amount);
                priceElem.val(price);
                break;
        }
        //金额 = 汇率 * 原币
        value = money * rate;
        this.setText(e, this.getElement(e, elem), value);
    },
    //外币（数量）核算金额反算汇率
    countRate_currency:function(e, elem){
        var tr = elem.closest('tr');
        var rateElem = tr.find('.col-currency [name="rate"]');
        var moneyElem = tr.find('.col-currency [name="money"]');
        var amountElem = tr.find('.col-number [name="amount"]');
        var value = elem.val();
        var amount = this.equalDir(parseFloat(amountElem.val() || 0), value);
        var money = this.equalDir(parseFloat(moneyElem.val() || 0), value);

        amountElem.val(amount);
        moneyElem.val(money);
        rateElem.val(this.countValue(value, money))
    },
    showDate:function(e, elem){
        $.calendar({
            
        })
    }
})